//! 应用程序配置
//! 
//! conf.rs
//! 
//! (RUST) alone
//! 
//! Create time: 2025-09-22		alone
//! Update time: 2025-09-22		alone
//! 

use std::{fs, sync::OnceLock};

use anyhow::anyhow;
use serde::Deserialize;

static APP_CONFIG: OnceLock<AppConfig> = OnceLock::new();

pub fn init_config() 
	-> anyhow::Result<()>
{
	let content = match fs::read_to_string("application.yml") 
	{
		Ok(text) =>
		{
			text
		}
		Err(e) =>
		{
			return Err(anyhow!("打开配置文件: application.yml 失败，错误: {}", e));
		}
	};

	let cfg: AppConfig = match serde_yaml::from_str(&content)
	{
		Ok(c) => 
		{
			c
		}
		Err(e) => 
		{
			return Err(anyhow!("解析配置失败，错误: {}", e));
		}
	};

	if !(cfg.mode.client.open == true || cfg.mode.server.open == true)
	{
		return Err(anyhow!("配置文件中的 mode.client.open 和 mode.server.open 必须开启一个，或者两个都开启!!!"));
	}

	match APP_CONFIG.set(cfg)
	{
		_ => { /* 如果已经初始化了，那么这里什么都不做就可以了 */}
	}

	Ok(())
}

pub fn config() 
	-> &'static AppConfig
{
	APP_CONFIG.get().expect("配置没有初始化，请初始化配置!!!")
}

/// 应用程序配置
#[derive(Debug, Deserialize, Clone)]
pub struct AppConfig
{
	/// 模式
	pub mode: Mode,
	/// 日志
	pub logs: Logs,
}

/// 应用程序模式，可开启为客户端或服务端（可同时开启）
#[derive(Debug, Deserialize, Clone)]
pub struct Mode
{
	/// 作为客户端
	pub client: ModeSide,
	/// 作为服务端
	pub server: ModeSide,
}

/// 模式的相关配置
#[derive(Debug, Deserialize, Clone)]
pub struct ModeSide
{
	/// 是否打开该模式
	pub open: bool,
	/// 该模式使用的ip地址
	pub ip: String,
	/// 该模式使用的端口
	pub port: u16,
	/// 该模式使用的协议
	pub protocol: String,
}

/// 日志的相关配置
#[derive(Debug, Deserialize, Clone)]
#[serde(default)]
pub struct Logs
{
	/// 日志目录
	pub dir: String,
	/// 日志文件名
	pub file_name: String,
	/// 日志级别 debug/info
	pub level: String,
}

impl Default for Logs
{
	fn default() 
		-> Self 
	{
		Self { 
			dir: "./logs".to_string(), 
			file_name: "application.log".to_string(), 
			level: "info".to_string() 
		}	
	}
}

